/* eslint-disable no-console */
const fs = require("fs");
const { exec } = require("child_process");
const _ = require("lodash");
const path = require("path");
const mockServersPath = path.resolve(
  __dirname,
  "./proxy-interceptor-servers.json"
);

// 获取生成的接口内容
// 该方式可使用require，但是需要确保该文件是一定存在的
function getOriginalMocks() {
  const exists = fs.existsSync(mockServersPath);
  if (!exists) return;
  const file = fs.readFileSync(mockServersPath, "utf-8") || "[]";
  try {
    return JSON.parse(file);
  } catch (error) {
    return [];
  }
}

const originalMocks = getOriginalMocks() || [];

function writeMock(mocks) {
  fs.writeFileSync(mockServersPath, JSON.stringify(mocks));
  console.log("快速模拟接口生成成功");
  exec(`prettier --write ${mockServersPath}`, (err) => {
    if (err) {
      console.log("模拟接口文件格式化错误\n");
    } else {
      console.log("模拟接口文件格式化成功\n");
    }
  });
}

const debounceWriteMock = _.debounce(writeMock, 1000);

function proxyResHook(proxyRes, req, res, formatMock) {
  const { method: prevMethod, url: prevUrl } = req;
  const [url] = (prevUrl || "").split("?");
  const method = (prevMethod || "").toLowerCase();

  let buffer = Buffer.from("", "utf8");
  proxyRes.on("data", (chunk) => {
    buffer = Buffer.concat([buffer, chunk]);
  });
  proxyRes.on("end", () => {
    let data;
    try {
      data = JSON.parse(buffer);
    } catch (error) {
      return;
    }
    let mockRes = {
      url,
      method,
      data
    };
    if (typeof formatMock === "function") {
      mockRes = formatMock(url, method, data) || {};
    }

    const findIndex = originalMocks.findIndex((item) => {
      return item.method === mockRes.method && item.url === mockRes.url;
    });

    if (findIndex > -1) {
      console.log("update", mockRes.method, mockRes.url);
      originalMocks[findIndex].data = mockRes.data;
    } else {
      console.log("add", mockRes.method, mockRes.url);
      originalMocks.push(mockRes);
    }
    debounceWriteMock(originalMocks);
  });
}
module.exports = function proxyInterceptorHook(proxys, formatRes) {
  const onProxyRes = (proxyRes, req, res) =>
    proxyResHook(proxyRes, req, res, formatRes);
  const addProxys = Object.entries(proxys).map(([key, proxy]) => {
    if (typeof proxy === "string") {
      return [key, { target: proxy, onProxyRes }];
    }
    return [key, { ...proxy, onProxyRes }];
  });
  return Object.fromEntries(addProxys);
};
